/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DaveSexton.DocProject.Sandcastle.TopicManagement
{
	internal sealed partial class TopicFilterActionPanel : UserControl
	{
		#region Public Properties
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Control ErrorHostControl
		{
			get
			{
				return saveButton;
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool ApplyEnabled
		{
			set
			{
				findButton.Enabled = value;
				applyButton.Enabled = value;
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool SaveEnabled
		{
			set
			{
				saveButton.Enabled = value;
			}
		}

		[Category("Appearance"), DefaultValue(false)]
		public bool FindButtonVisible
		{
			get
			{
				// A field must be used instead of the button's Visible property since the designer, for some reason, likes to
				// reset the value when saving, even if it's explicitly set in the property grid.  Using ShouldSerialize* instead 
				// of DefaultValueAttribute does not help.  Using a backing field is the only thing that seems to help.
				return findButtonVisible;
			}
			set
			{
				findButton.Visible = findButtonVisible = value;
			}
		}
		#endregion

		#region Private / Protected
		private bool findButtonVisible;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="TopicFilterActionPanel" /> class.
		/// </summary>
		public TopicFilterActionPanel()
		{
			InitializeComponent();

			((Bitmap) foundPicture.Image).MakeTransparent(Color.Fuchsia);
			((Bitmap) appliedPicture.Image).MakeTransparent(Color.Fuchsia);
		}
		#endregion

		#region Methods
		public void ResetSearch()
		{
			foundPicture.Visible = false;
			appliedPicture.Visible = false;
		}

		public void SearchComplete(bool findOnly, bool check, bool nextOnly, int matchCount)
		{
			foundPicture.Visible = findOnly;
			appliedPicture.Visible = !findOnly;

			PictureBox picture = (findOnly) ? foundPicture : appliedPicture;

			string tip = string.Format(System.Globalization.CultureInfo.CurrentCulture,
				(findOnly)
				? (nextOnly)
					? (matchCount == 0)
						? Resources.Text.TopicFilterNextMatchNotFound
						: Resources.Text.TopicFilterFoundNextMatchOnly
					: Resources.Text.TopicFilterFoundAllMatches
				: (nextOnly)
					? (matchCount == 0)
						? Resources.Text.TopicFilterNextMatchNotFound
						: (check)
							? Resources.Text.TopicFilterIncludedNextMatchOnly
							: Resources.Text.TopicFilterExcludedNextMatchOnly
					: (check)
						? Resources.Text.TopicFilterIncludedAllMatches
						: Resources.Text.TopicFilterExcludedAllMatches,
				matchCount);

			toolTip1.SetToolTip(picture, tip);
			toolTip1.Show(tip, picture, 0, picture.Height + 2, 1500);
		}
		#endregion

		#region Events
		private readonly object SaveEvent = new object();
		private readonly object ApplyEvent = new object();
		private readonly object NextMatchEvent = new object();
		private readonly object FindEvent = new object();

		/// <summary>
		/// Event raised when the Find button is clicked.
		/// </summary>
		[Category("Action")]
		[Description("Event raised when the Find button is clicked.")]
		public event EventHandler<EventArgs> Find
		{
			add
			{
				lock (FindEvent)
				{
					Events.AddHandler(FindEvent, value);
				}
			}
			remove
			{
				lock (FindEvent)
				{
					Events.RemoveHandler(FindEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="Find" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnFind(EventArgs e)
		{
			EventHandler<EventArgs> handler = null;

			lock (FindEvent)
			{
				handler = (EventHandler<EventArgs>) Events[FindEvent];
			}

			if (handler != null)
				handler(this, e);
		}

		/// <summary>
		/// Event raised when the next match should be selected.
		/// </summary>
		[Category("Action")]
		[Description("Event raised when the next match should be selected.")]
		public event EventHandler NextMatch
		{
			add
			{
				lock (NextMatchEvent)
				{
					Events.AddHandler(NextMatchEvent, value);
				}
			}
			remove
			{
				lock (NextMatchEvent)
				{
					Events.RemoveHandler(NextMatchEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="NextMatch" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnNextMatch(EventArgs e)
		{
			EventHandler handler = null;

			lock (NextMatchEvent)
			{
				handler = (EventHandler) Events[NextMatchEvent];
			}

			if (handler != null)
				handler(this, e);
		}

		/// <summary>
		/// Event raised when the Apply button is clicked.
		/// </summary>
		[Category("Action")]
		[Description("Event raised when the Apply button is clicked.")]
		public event EventHandler Apply
		{
			add
			{
				lock (ApplyEvent)
				{
					Events.AddHandler(ApplyEvent, value);
				}
			}
			remove
			{
				lock (ApplyEvent)
				{
					Events.RemoveHandler(ApplyEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="Apply" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnApply(EventArgs e)
		{
			EventHandler handler = null;

			lock (ApplyEvent)
			{
				handler = (EventHandler) Events[ApplyEvent];
			}

			if (handler != null)
				handler(this, e);
		}

		/// <summary>
		/// Event raised when the Save button is clicked.
		/// </summary>
		[Category("Action")]
		[Description("Event raised when the Save button is clicked.")]
		public event EventHandler Save
		{
			add
			{
				lock (SaveEvent)
				{
					Events.AddHandler(SaveEvent, value);
				}
			}
			remove
			{
				lock (SaveEvent)
				{
					Events.RemoveHandler(SaveEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="Save" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnSave(EventArgs e)
		{
			EventHandler handler = null;

			lock (SaveEvent)
			{
				handler = (EventHandler) Events[SaveEvent];
			}

			if (handler != null)
				handler(this, e);
		}
		#endregion

		#region Event Handlers
		private void saveButton_Click(object sender, EventArgs e)
		{
			OnSave(e);
		}

		private void findButton_Click(object sender, EventArgs e)
		{
			OnFind(e);
		}

		private void applyButton_Click(object sender, EventArgs e)
		{
			OnApply(e);
		}

		private void appliedPicture_Click(object sender, EventArgs e)
		{
			OnNextMatch(e);
		}

		private void foundPicture_Click(object sender, EventArgs e)
		{
			OnNextMatch(e);
		}
		#endregion

		#region Nested
		private sealed class SingleClickPictureBox : PictureBox
		{
			#region Constructors
			/// <summary>
			/// Constructs a new instance of the <see cref="SingleClickPictureBox" /> class.
			/// </summary>
			public SingleClickPictureBox()
			{
				SetStyle(ControlStyles.StandardDoubleClick, false);
			}
			#endregion
		}
		#endregion
	}
}
